1 /// Credit BinaryX
2 ///
Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
3 ///
Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
4 ///
Update by xesenix - rewrote almost the entire code
5 ///
- configuration for direction move instead of 2 concurrent class (easier to change direction in editor)
6 ///
- supports list layout with horizontal or vertical layout need to match direction with type of layout used
7 ///
- dynamic checks if scrolled list size changes and recalculates anchor positions
8 ///
and item size based on itemsVisibleAtOnce and size of root container
9 ///
if you don't wish to use this auto resize turn of autoLayoutItems
10 ///
- fixed current page made it independent from pivot
11 ///
- replaced pagination with delegate function
12 using
System;
13 using
UnityEngine.EventSystems;
14
15 namespace
UnityEngine.UI.Extensions
16 {
17     
[ExecuteInEditMode]
18     
[RequireComponent(typeof(ScrollRect))]
19     
[AddComponentMenu("UI/Extensions/Scroll Snap")]
20     
public class ScrollSnap : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
21     {
22         
// needed because of reversed behaviour of axis Y compared to X
23         
// (positions of children lower in children list in horizontal directions grows when in vertical it gets smaller)
24         
public enum ScrollDirection
25         {
26             Horizontal,
27             Vertical
28         }
29
30         
public delegate void PageSnapChange(int page);
31
32         
public event PageSnapChange onPageChange;
33
34         
public ScrollDirection direction = ScrollDirection.Horizontal;
35
36         
protected ScrollRect scrollRect;
37
38         
protected RectTransform scrollRectTransform;
39
40         
protected Transform listContainerTransform;
41
42         
protected RectTransform rectTransform;
43
44         
int pages;
45
46         
protected int startingPage = 0;
47
48         
// anchor points to lerp to to see child on certain indexes
49         
protected Vector3[] pageAnchorPositions;
50
51         
protected Vector3 lerpTarget;
52
53         
protected bool lerp;
54
55         
// item list related
56         
protected float listContainerMinPosition;
57
58         
protected float listContainerMaxPosition;
59
60         
protected float listContainerSize;
61
62         
protected RectTransform listContainerRectTransform;
63
64         
protected Vector2 listContainerCachedSize;
65
66         
protected float itemSize;
67
68         
protected int itemsCount = 0;
69
70         
[Tooltip("Button to go to the next page. (optional)")]
71         
public Button nextButton;
72
73         
[Tooltip("Button to go to the previous page. (optional)")]
74         
public Button prevButton;
75
76         
[Tooltip("Number of items visible in one page of scroll frame.")]
77         
[RangeAttribute(1, 100)]
78         
public int itemsVisibleAtOnce = 1;
79
80         
[Tooltip("Sets minimum width of list items to 1/itemsVisibleAtOnce.")]
81         
public bool autoLayoutItems = true;
82
83         
[Tooltip("If you wish to update scrollbar numberOfSteps to number of active children on list.")]
84         
public bool linkScrolbarSteps = false;
85
86         
[Tooltip("If you wish to update scrollrect sensitivity to size of list element.")]
87         
public bool linkScrolrectScrollSensitivity = false;
88
89         
public Boolean useFastSwipe = true;
90
91         
public int fastSwipeThreshold = 100;
92
93         
// drag related
94         
protected bool startDrag = true;
95
96         
protected Vector3 positionOnDragStart = new Vector3();
97
98         
protected int pageOnDragStart;
99
100         
protected bool fastSwipeTimer = false;
101
102         
protected int fastSwipeCounter = 0;
103
104         
protected int fastSwipeTarget = 10;
105
106         
// Use this for initialization
107         
void Awake()
108         {
109             lerp =
false;
110
111             scrollRect = gameObject.GetComponent<ScrollRect>();
112             scrollRectTransform = gameObject.GetComponent<RectTransform>();
113             listContainerTransform = scrollRect.content;
114             listContainerRectTransform = listContainerTransform.GetComponent<RectTransform>();
115
116             rectTransform = listContainerTransform.gameObject.GetComponent<RectTransform>();
117             UpdateListItemsSize();
118             UpdateListItemPositions();
119
120             PageChanged(CurrentPage());
121
122             
if (nextButton)
123             {
124                 nextButton.GetComponent<Button>().onClick.AddListener(() =>
125                 {
126                     NextScreen();
127                 });
128             }
129
130             
if (prevButton)
131             {
132                 prevButton.GetComponent<Button>().onClick.AddListener(() =>
133                 {
134                     PreviousScreen();
135                 });
136             }
137         }
138
139         
void Start()
140         {
141             Awake();
142         }
143
144         
public void UpdateListItemsSize()
145         {
146             
float size = 0;
147             
float currentSize = 0;
148             
if (direction == ScrollSnap.ScrollDirection.Horizontal)
149             {
150                 size = scrollRectTransform.rect.width / itemsVisibleAtOnce;
151                 currentSize = listContainerRectTransform.rect.width / itemsCount;
152             }
153             
else
154             {
155                 size = scrollRectTransform.rect.height / itemsVisibleAtOnce;
156                 currentSize = listContainerRectTransform.rect.height / itemsCount;
157             }
158
159             itemSize = size;
160
161             
if (linkScrolrectScrollSensitivity)
162             {
163                 scrollRect.scrollSensitivity = itemSize;
164             }
165
166             
if (autoLayoutItems && currentSize != size && itemsCount > 0)
167             {
168                 
if (direction == ScrollSnap.ScrollDirection.Horizontal)
169                 {
170                     
foreach (var tr in listContainerTransform)
171                     {
172                         GameObject child = ((Transform)tr).gameObject;
173                         
if (child.activeInHierarchy)
174                         {
175                             
var childLayout = child.GetComponent<LayoutElement>();
176
177                             
if (childLayout == null)
178                             {
179                                 childLayout = child.AddComponent<LayoutElement>();
180                             }
181
182                             childLayout.minWidth = itemSize;
183                         }
184                     }
185                 }
186                 
else
187                 {
188                     
foreach (var tr in listContainerTransform)
189                     {
190                         GameObject child = ((Transform)tr).gameObject;
191                         
if (child.activeInHierarchy)
192                         {
193                             
var childLayout = child.GetComponent<LayoutElement>();
194
195                             
if (childLayout == null)
196                             {
197                                 childLayout = child.AddComponent<LayoutElement>();
198                             }
199
200                             childLayout.minHeight = itemSize;
201                         }
202                     }
203                 }
204             }
205         }
206
207         
public void UpdateListItemPositions()
208         {
209             
if (!listContainerRectTransform.rect.size.Equals(listContainerCachedSize))
210             {
211                 
// checking how many children of list are active
212                 
int activeCount = 0;
213
214                 
foreach (var tr in listContainerTransform)
215                 {
216                     
if (((Transform)tr).gameObject.activeInHierarchy)
217                     {
218                         activeCount++;
219                     }
220                 }
221
222                 
// if anything changed since last check reinitialize anchors list
223                 itemsCount =
0;
224                 Array.Resize(
ref pageAnchorPositions, activeCount);
225
226                 
if (activeCount > 0)
227                 {
228                     pages = Mathf.Max(activeCount - itemsVisibleAtOnce +
1, 1);
229
230                     
if (direction == ScrollDirection.Horizontal)
231                     {
232                         
// looking for list spanning range min/max
233                         scrollRect.horizontalNormalizedPosition =
0;
234                         listContainerMaxPosition = listContainerTransform.localPosition.x;
235                         scrollRect.horizontalNormalizedPosition =
1;
236                         listContainerMinPosition = listContainerTransform.localPosition.x;
237
238                         listContainerSize = listContainerMaxPosition - listContainerMinPosition;
239
240                         
for (var i = 0; i < pages; i++)
241                         {
242                             pageAnchorPositions[i] =
new Vector3(
243                                 listContainerMaxPosition - itemSize * i,
244                                 listContainerTransform.localPosition.y,
245                                 listContainerTransform.localPosition.z
246                             );
247                         }
248                     }
249                     
else
250                     {
251                         
//Debug.Log ("-------------looking for list spanning range----------------");
252                         
// looking for list spanning range
253                         scrollRect.verticalNormalizedPosition =
1;
254                         listContainerMinPosition = listContainerTransform.localPosition.y;
255                         scrollRect.verticalNormalizedPosition =
0;
256                         listContainerMaxPosition = listContainerTransform.localPosition.y;
257
258                         listContainerSize = listContainerMaxPosition - listContainerMinPosition;
259
260                         
for (var i = 0; i < pages; i++)
261                         {
262                             pageAnchorPositions[i] =
new Vector3(
263                                 listContainerTransform.localPosition.x,
264                                 listContainerMinPosition + itemSize * i,
265                                 listContainerTransform.localPosition.z
266                             );
267                         }
268                     }
269
270                     UpdateScrollbar(linkScrolbarSteps);
271                     startingPage = Mathf.Min(startingPage, pages);
272                     ResetPage();
273                 }
274
275                 
if (itemsCount != activeCount)
276                 {
277                     PageChanged(CurrentPage());
278                 }
279
280                 itemsCount = activeCount;
281                 listContainerCachedSize.Set(listContainerRectTransform.rect.size.x, listContainerRectTransform.rect.size.y);
282             }
283
284         }
285
286         
public void ResetPage()
287         {
288             
if (direction == ScrollDirection.Horizontal)
289             {
290                 scrollRect.horizontalNormalizedPosition = pages >
1 ? (float)startingPage / (float)(pages - 1) : 0;
291             }
292             
else
293             {
294                 scrollRect.verticalNormalizedPosition = pages >
1 ? (float)(pages - startingPage - 1) / (float)(pages - 1) : 0;
295             }
296         }
297
298         
protected void UpdateScrollbar(bool linkSteps)
299         {
300             
if (linkSteps)
301             {
302                 
if (direction == ScrollDirection.Horizontal)
303                 {
304                     
if (scrollRect.horizontalScrollbar != null)
305                     {
306                         scrollRect.horizontalScrollbar.numberOfSteps = pages;
307                     }
308                 }
309                 
else
310                 {
311                     
if (scrollRect.verticalScrollbar != null)
312                     {
313                         scrollRect.verticalScrollbar.numberOfSteps = pages;
314                     }
315                 }
316             }
317             
else
318             {
319                 
if (direction == ScrollDirection.Horizontal)
320                 {
321                     
if (scrollRect.horizontalScrollbar != null)
322                     {
323                         scrollRect.horizontalScrollbar.numberOfSteps =
0;
324                     }
325                 }
326                 
else
327                 {
328                     
if (scrollRect.verticalScrollbar != null)
329                     {
330                         scrollRect.verticalScrollbar.numberOfSteps =
0;
331                     }
332                 }
333             }
334         }
335
336         
void LateUpdate()
337         {
338             UpdateListItemsSize();
339             UpdateListItemPositions();
340
341             
if (lerp)
342             {
343                 UpdateScrollbar(
false);
344
345                 listContainerTransform.localPosition = Vector3.Lerp(listContainerTransform.localPosition, lerpTarget,
7.5f * Time.deltaTime);
346
347                 
if (Vector3.Distance(listContainerTransform.localPosition, lerpTarget) < 0.001f)
348                 {
349                     listContainerTransform.localPosition = lerpTarget;
350                     lerp =
false;
351
352                     UpdateScrollbar(linkScrolbarSteps);
353                 }
354
355                 
//change the info bullets at the bottom of the screen. Just for visual effect
356                 
if (Vector3.Distance(listContainerTransform.localPosition, lerpTarget) < 10f)
357                 {
358                     PageChanged(CurrentPage());
359                 }
360             }
361
362             
if (fastSwipeTimer)
363             {
364                 fastSwipeCounter++;
365             }
366         }
367
368         
private bool fastSwipe = false; //to determine if a fast swipe was performed
369
370
371         
//Function for switching screens with buttons
372         
public void NextScreen()
373         {
374             UpdateListItemPositions();
375
376             
if (CurrentPage() < pages - 1)
377             {
378                 lerp =
true;
379                 lerpTarget = pageAnchorPositions[CurrentPage() +
1];
380
381                 PageChanged(CurrentPage() +
1);
382             }
383         }
384
385         
//Function for switching screens with buttons
386         
public void PreviousScreen()
387         {
388             UpdateListItemPositions();
389
390             
if (CurrentPage() > 0)
391             {
392                 lerp =
true;
393                 lerpTarget = pageAnchorPositions[CurrentPage() -
1];
394
395                 PageChanged(CurrentPage() -
1);
396             }
397         }
398
399         
//Because the CurrentScreen function is not so reliable, these are the functions used for swipes
400         
private void NextScreenCommand()
401         {
402             
if (pageOnDragStart < pages - 1)
403             {
404                 
int targetPage = Mathf.Min(pages - 1, pageOnDragStart + itemsVisibleAtOnce);
405                 lerp =
true;
406
407                 lerpTarget = pageAnchorPositions[targetPage];
408
409                 PageChanged(targetPage);
410             }
411         }
412
413         
//Because the CurrentScreen function is not so reliable, these are the functions used for swipes
414         
private void PrevScreenCommand()
415         {
416             
if (pageOnDragStart > 0)
417             {
418                 
int targetPage = Mathf.Max(0, pageOnDragStart - itemsVisibleAtOnce);
419                 lerp =
true;
420
421                 lerpTarget = pageAnchorPositions[targetPage];
422
423                 PageChanged(targetPage);
424             }
425         }
426
427
428         
//returns the current screen that the is seeing
429         
public int CurrentPage()
430         {
431             
float pos;
432
433             
if (direction == ScrollDirection.Horizontal)
434             {
435                 pos = listContainerMaxPosition - listContainerTransform.localPosition.x;
436                 pos = Mathf.Clamp(pos,
0, listContainerSize);
437             }
438             
else
439             {
440                 pos = listContainerTransform.localPosition.y - listContainerMinPosition;
441                 pos = Mathf.Clamp(pos,
0, listContainerSize);
442             }
443
444             
float page = pos / itemSize;
445
446             
return Mathf.Clamp(Mathf.RoundToInt(page), 0, pages);
447         }
448
449         
public void ChangePage(int page)
450         {
451             
if (0 <= page && page < pages)
452             {
453                 lerp =
true;
454
455                 lerpTarget = pageAnchorPositions[page];
456
457                 PageChanged(page);
458             }
459         }
460
461         
//changes the bullets on the bottom of the page - pagination
462         
private void PageChanged(int currentPage)
463         {
464             startingPage = currentPage;
465
466             
if (nextButton)
467             {
468                 nextButton.interactable = currentPage < pages -
1;
469             }
470
471             
if (prevButton)
472             {
473                 prevButton.interactable = currentPage >
0;
474             }
475
476             
if (onPageChange != null)
477             {
478                 onPageChange(currentPage);
479             }
480         }
481
482         
#region Interfaces
483         
public void OnBeginDrag(PointerEventData eventData)
484         {
485             UpdateScrollbar(
false);
486
487             fastSwipeCounter =
0;
488             fastSwipeTimer =
true;
489
490             positionOnDragStart = eventData.position;
491             pageOnDragStart = CurrentPage();
492         }
493
494         
public void OnEndDrag(PointerEventData eventData)
495         {
496             startDrag =
true;
497             
float change = 0;
498
499             
if (direction == ScrollDirection.Horizontal)
500             {
501                 change = positionOnDragStart.x - eventData.position.x;
502             }
503             
else
504             {
505                 change = -positionOnDragStart.y + eventData.position.y;
506             }
507
508             
if (useFastSwipe)
509             {
510                 fastSwipe =
false;
511                 fastSwipeTimer =
false;
512
513                 
if (fastSwipeCounter <= fastSwipeTarget)
514                 {
515                     
if (Math.Abs(change) > fastSwipeThreshold)
516                     {
517                         fastSwipe =
true;
518                     }
519                 }
520                 
if (fastSwipe)
521                 {
522                     
if (change > 0)
523                     {
524                         NextScreenCommand();
525                     }
526                     
else
527                     {
528                         PrevScreenCommand();
529                     }
530                 }
531                 
else
532                 {
533                     lerp =
true;
534                     lerpTarget = pageAnchorPositions[CurrentPage()];
535                 }
536             }
537             
else
538             {
539                 lerp =
true;
540                 lerpTarget = pageAnchorPositions[CurrentPage()];
541             }
542         }
543
544         
public void OnDrag(PointerEventData eventData)
545         {
546             lerp =
false;
547
548             
if (startDrag)
549             {
550                 OnBeginDrag(eventData);
551                 startDrag =
false;
552             }
553         }
554         
#endregion
555     }
556 }


Credit BinaryX

Sourced from - http:forum.unity3d.comthreadsscripts-useful-4-6-scripts-collection.264161page-2#post-1945602

Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.

Update by xesenix - rewrote almost the entire code

- configuration for direction move instead of 2 concurrent class (easier to change direction in editor)

- supports list layout with horizontal or vertical layout need to match direction with type of layout used

- dynamic checks if scrolled list size changes and recalculates anchor positions

and item size based on itemsVisibleAtOnce and size of root container

if you don't wish to use this auto resize turn of autoLayoutItems

- fixed current page made it independent from pivot

- replaced pagination with delegate function

needed because of reversed behaviour of axis Y compared to X

(positions of children lower in children list in horizontal directions grows when in vertical it gets smaller)

anchor points to lerp to to see child on certain indexes

item list related

drag related

Use this for initialization

checking how many children of list are active

if anything changed since last check reinitialize anchors list

looking for list spanning range minmax

Debug.Log ("-------------looking for list spanning range----------------");

looking for list spanning range

change the info bullets at the bottom of the screen. Just for visual effect

private bool fastSwipe = false; to determine if a fast swipe was performed

Function for switching screens with buttons

Function for switching screens with buttons

Because the CurrentScreen function is not so reliable, these are the functions used for swipes

Because the CurrentScreen function is not so reliable, these are the functions used for swipes

returns the current screen that the is seeing

changes the bullets on the bottom of the page - pagination




Trò chơi đua xe động vật trong UNITY Engine 114.792 lượt xem

Gõ tìm kiếm nhanh...